"""
本地RTSP服务器
使用FFmpeg将本地摄像头流转换为RTSP流
"""

import subprocess
import sys
import time
import threading
import os
import signal

class RTSPServer:
    def __init__(self, rtsp_port=8554, stream_name="stream"):
        self.rtsp_port = rtsp_port
        self.stream_name = stream_name
        self.process = None
        self.running = False
        
    def start_server(self):
        """启动RTSP服务器"""
        try:
            print(f"正在启动RTSP服务器...")
            print(f"端口: {self.rtsp_port}")
            print(f"流名称: {self.stream_name}")
            print(f"RTSP地址: rtsp://localhost:{self.rtsp_port}/{self.stream_name}")
            
            # FFmpeg命令：从本地摄像头创建RTSP流
            # Windows下使用dshow捕获摄像头
            cmd = [
                'ffmpeg',
                '-f', 'dshow',
                '-i', 'video=HP True Vision FHD Camera',  # 使用虚拟摄像头
                '-c:v', 'libx264',           # 视频编码器
                '-preset', 'ultrafast',      # 编码预设（快速）
                '-tune', 'zerolatency',      # 零延迟调优
                '-r', '30',                  # 帧率
                '-s', '640x480',             # 分辨率
                '-b:v', '1M',                # 比特率
                '-maxrate', '1M',            # 最大比特率
                '-bufsize', '2M',            # 缓冲区大小
                '-pix_fmt', 'yuv420p',       # 像素格式
                '-g', '60',                  # GOP大小
                '-f', 'rtsp',                # 输出格式
                f'rtsp://localhost:{self.rtsp_port}/{self.stream_name}'
            ]
            
            print(f"FFmpeg命令: {' '.join(cmd)}")
            
            # 启动FFmpeg进程
            self.process = subprocess.Popen(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                universal_newlines=True
            )
            
            self.running = True
            
            # 监控输出
            def monitor_output():
                for line in iter(self.process.stderr.readline, ''):
                    if line:
                        print(f"FFmpeg: {line.strip()}")
                        
            monitor_thread = threading.Thread(target=monitor_output, daemon=True)
            monitor_thread.start()
            
            print("RTSP服务器已启动！")
            print("客户端可以使用以下地址连接:")
            print(f"  rtsp://localhost:{self.rtsp_port}/{self.stream_name}")
            print("按 Ctrl+C 停止服务器")
            
            # 等待进程结束
            self.process.wait()
            
        except FileNotFoundError:
            print("错误: 未找到FFmpeg。请确保FFmpeg已安装并添加到PATH环境变量中。")
            print("下载地址: https://ffmpeg.org/download.html")
        except KeyboardInterrupt:
            print("\n正在停止RTSP服务器...")
            self.stop_server()
        except Exception as e:
            print(f"启动RTSP服务器失败: {e}")
            
    def stop_server(self):
        """停止RTSP服务器"""
        self.running = False
        if self.process:
            try:
                self.process.terminate()
                self.process.wait(timeout=5)
            except subprocess.TimeoutExpired:
                self.process.kill()
            print("RTSP服务器已停止")

def list_cameras():
    """列出可用的摄像头设备"""
    print("正在检测可用的摄像头设备...")
    try:
        cmd = [
            'ffmpeg',
            '-f', 'dshow',
            '-list_devices', 'true',
            '-i', 'dummy'        ]
        
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=10, encoding='utf-8', errors='ignore')
        output = result.stderr
        
        print("可用的视频设备:")
        lines = output.split('\n')
        for line in lines:
            if 'DirectShow video devices' in line or '"' in line:
                print(f"  {line.strip()}")
                
    except Exception as e:
        print(f"检测摄像头设备失败: {e}")

def main():
    if len(sys.argv) > 1 and sys.argv[1] == '--list':
        list_cameras()
        return
        
    # 检查FFmpeg是否可用
    try:
        subprocess.run(['ffmpeg', '-version'], capture_output=True, check=True)
    except (FileNotFoundError, subprocess.CalledProcessError):
        print("错误: FFmpeg未安装或不在PATH中")
        print("请从 https://ffmpeg.org/download.html 下载并安装FFmpeg")
        return
        
    # 启动RTSP服务器
    server = RTSPServer()
    
    # 处理Ctrl+C信号
    def signal_handler(sig, frame):
        print("\n收到停止信号...")
        server.stop_server()
        sys.exit(0)
        
    signal.signal(signal.SIGINT, signal_handler)
    
    try:
        server.start_server()
    except KeyboardInterrupt:
        server.stop_server()

if __name__ == "__main__":
    main()
